package com.lunker.moneyrecord;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

public class CategoryChartActivity extends Activity implements OnClickListener, OnTouchListener {
	
	private SQLiteDatabase mDB = null;
	private ListView mCategoryList = null;
	private Calendar mDisplayDate = null;
	private TextView mThisMonth = null;
	private TextView mTotal = null;
	private SimpleDateFormat mDateFormat = null;
	private static final int MY_ACTION_NONE = 0;
	private static final int MY_ACTION_FLING = 1;
	private int myAction = MY_ACTION_NONE;
	private float mLastX = 0;
	private float mLasty = 0;
	private int MIN_TOUCH_SLOP = 0;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.category_chart);
		
		mDB = new MyDatabaseOpenHelper(this).getReadableDatabase();
		mCategoryList = (ListView) findViewById(R.id.ltv_category_list);
		mThisMonth = (TextView) findViewById(R.id.txt_thisMonth);
		mTotal = (TextView) findViewById(R.id.txt_total_value);
		mDisplayDate = Calendar.getInstance();		
		mDateFormat = new SimpleDateFormat("yyyy - MM");
		MIN_TOUCH_SLOP = ViewConfiguration.get(this).getScaledTouchSlop();
		
		mCategoryList.setOnTouchListener(this);
		
		updateDisplayDate();
		updateChart();
	}

	@Override
	protected void onDestroy() {
		if (mDB != null) {
			mDB.close();
		}
		super.onDestroy();
	}
	
	@Override
	public boolean onTouch(View v, MotionEvent ev) {
		int act = ev.getAction();
		
		if (myAction == MY_ACTION_FLING && act == MotionEvent.ACTION_MOVE) {
			//Ignore move events while flinging.
			return true; //Don't pass this event to ListView's onTouchEvent();
		}
		
		switch (act) {
		case MotionEvent.ACTION_MOVE:
				float diffX = mLastX - ev.getX();
				float diffY = mLasty - ev.getY();
				
				if (Math.abs(diffX) < MIN_TOUCH_SLOP || Math.abs(diffY) >= MIN_TOUCH_SLOP) {
					//Not the fling gesture we want, pass it to ListView's onTouchEvent().
					return false;
				} else {
					myAction = MY_ACTION_FLING;
				}
				
				if (diffX > 0) {
					mDisplayDate.add(Calendar.MONTH, 1);
				} else if (diffX < 0){
					mDisplayDate.add(Calendar.MONTH, -1);
				}
				
				//Cancel child actions.
				MotionEvent cEvent = MotionEvent.obtain(ev);
				cEvent.setAction(MotionEvent.ACTION_CANCEL);
				dispatchTouchEvent(cEvent);
				
				updateDisplayDate();
				updateChart();
				return true;
		case MotionEvent.ACTION_DOWN:
			mLastX = ev.getX();
			mLasty = ev.getY();
		case MotionEvent.ACTION_UP:
			myAction = MY_ACTION_NONE;
		default:
			return false;
		}
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.btn_nextMonth:
			mDisplayDate.add(Calendar.MONTH, 1);
			updateDisplayDate();
			updateChart();
			break;
		case R.id.btn_prevMonth:
			mDisplayDate.add(Calendar.MONTH, -1);
			updateDisplayDate();
			updateChart();
			break;
		case R.id.txt_thisMonth:
			mDisplayDate = Calendar.getInstance();
			updateDisplayDate();
			updateChart();
			Toast.makeText(this, getText(R.string.returned_to_this_month), 
					Toast.LENGTH_SHORT).show();
			break;		
		}
	}
	
	private void updateDisplayDate () {
		mThisMonth.setText(mDateFormat.format(mDisplayDate.getTime()));
	}
	
	private void updateChart () {
		String year = Integer.toString(mDisplayDate.get(Calendar.YEAR));
		String month = Integer.toString(mDisplayDate.get(Calendar.MONTH));
		
		Cursor crSum = mDB.query(
				"money_record",
				new String[] {
						"total(amount) as sum"
				},
				"year = ? and month = ?", 
				new String[] {
					year,
					month
				},
				null,
				null,
				null);
		startManagingCursor(crSum);
		crSum.moveToFirst();
		float sum = crSum.getFloat(0);
		mTotal.setText(Float.toString(sum));
		
		Cursor crList = mDB.query(
				new StringBuilder("category left join money_record on cid = category")
					.append(" and year = ")
					.append(year)
					.append(" and month = ")
					.append(month).toString(),
				new String[] {
						"cid as _id",
						"cname", 
						"total(amount) as sum"
				},
				null, 
				null,
				"cid",
				null,
				"cid asc");
		startManagingCursor(crList);
		
		CategoryListAdapter adapter = new CategoryListAdapter(this, crList, sum);
		mCategoryList.setAdapter(adapter);
		adapter.notifyDataSetChanged();
	}

	private class CategoryListAdapter extends CursorAdapter {
		
		private LayoutInflater mInflator = null;
		private float mTotal = 0;
		private DecimalFormat mFormat = null;

		public CategoryListAdapter(Context context, Cursor c, float total) {
			super(context, c);
			mInflator = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			mTotal = total;
			mFormat = new DecimalFormat("0.0%");
		}

		@Override
		public void bindView(View view, Context context, Cursor cursor) {
			ViewHolder holder = (ViewHolder) view.getTag();
			String title = cursor.getString(cursor.getColumnIndex("cname"));
			float amount = cursor.getFloat(cursor.getColumnIndex("sum"));
			float percentage = amount / mTotal;
			
			if (Float.isNaN(percentage)) {
				percentage = 0;
			}
			
			String perc = mFormat.format(percentage);			
			holder.title.setText(title);
			holder.percent_bar.setMax(Math.round(mTotal));
			holder.percent_bar.setProgress(Math.round(amount));
			holder.amount.setText(Float.toString(amount));
			holder.percent.setText(perc);
		}

		@Override
		public View newView(Context context, Cursor cursor, ViewGroup parent) {
			View v = mInflator.inflate(R.layout.category_item, parent, false);
			ViewHolder holder = new ViewHolder();
			holder.title = (TextView) v.findViewById(R.id.txt_category_name);
			holder.percent_bar = (ProgressBar) v.findViewById(R.id.pgb_category_percent);
			holder.amount = (TextView) v.findViewById(R.id.txt_category_amount);
			holder.percent = (TextView) v.findViewById(R.id.txt_category_percent);
			v.setTag(holder);
			return v;
		}
		
		private class ViewHolder {
			public TextView title = null;
			public ProgressBar percent_bar = null;
			public TextView amount = null;
			public TextView percent = null;
		}
	}

}
